package work.timejay.user.service.books.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.multipart.MultipartFile;
import sun.rmi.log.LogHandler;
import work.timejay.common.ApiPageEntity;
import work.timejay.constants.CommonConstants;
import work.timejay.constants.RedisConstants;
import work.timejay.entity.User;
import work.timejay.user.bo.BooksFindBO;
import work.timejay.user.dto.books.UserBookSaveDTO;
import work.timejay.user.dto.books.UserBooksPageDTO;
import work.timejay.user.entity.books.BookType;
import work.timejay.user.entity.books.Books;
import work.timejay.user.entity.books.UserBooks;
import work.timejay.user.mapper.books.UserBooksMapper;
import work.timejay.user.service.books.BooksService;
import work.timejay.user.service.books.UserBooksService;
import work.timejay.common.SuperServiceImpl;
import org.springframework.stereotype.Service;
import work.timejay.user.service.users.UserService;
import work.timejay.user.vo.books.UserBooksPageVO;
import work.timejay.user.vo.users.UserBookLikeVO;
import work.timejay.utils.FileUtils;
import work.timejay.utils.LoginHelper;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 用户书本表 服务实现类
 * </p>
 *
 * @author 王文杰
 * @since 2023-11-29
 */
@Service
public class UserBooksServiceImpl extends SuperServiceImpl<UserBooksMapper, UserBooks> implements UserBooksService {

    @Autowired
    private UserService userService;

    @Autowired
    private FileUtils fileUtils;

    @Autowired
    private BooksService booksService;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;


    @Override
    public BooksFindBO findBookOneDayReadNumById(Long bookId) {
        BooksFindBO voBean = new BooksFindBO();
        //获取用户与该book关系数据
        UserBooks userBooks = lambdaQuery()
                .eq(UserBooks::getBookId, bookId)
                .eq(UserBooks::getUserId, LoginHelper.loginUserInfo().getId())
                .one();
        voBean.setGiveStatus(0);
        if (null != userBooks && userBooks.getGiveStatus()) {
            voBean.setGiveStatus(1);
        }
        LocalDateTime max = LocalDateTime.of(LocalDate.from(LocalDateTime.now()), LocalDateTime.MAX.toLocalTime());
        LocalDateTime min = LocalDateTime.of(LocalDate.from(LocalDateTime.now()), LocalDateTime.MIN.toLocalTime());
        Integer dayReadNum = lambdaQuery()
                .eq(UserBooks::getBookId, bookId)
                .between(UserBooks::getCreateTime, min, max)
                .count();
        voBean.setReadNum(dayReadNum);
        voBean.setPushNum(60);
        List<UserBooks> list = lambdaQuery()
                .eq(UserBooks::getBookId, bookId)
                .orderByDesc(UserBooks::getCreateTime)
                .last("LIMIT 3")
                .list();
        List<UserBookLikeVO> userBookLikeVOList = BeanUtil.copyToList(list, UserBookLikeVO.class);
        userBookLikeVOList.forEach(e -> {
            User user = userService.findUserById(e.getUserId());
            if (null != user) {
                e.setUserName(user.getName());
                e.setLogoPath(fileUtils.preview(user.getLogoPath()));
            }
        });
        voBean.setOtherList(userBookLikeVOList);
        return voBean;
    }

    @Override
    public void saveBook(UserBookSaveDTO dto) {
        UserBooks userBooks = lambdaQuery()
                .eq(UserBooks::getBookId, dto.getBookId())
                .eq(UserBooks::getUserId, LoginHelper.loginUserInfo().getId())
                .one();
        if (null == userBooks) {
            Books books = booksService.findBooksById(dto.getBookId(),false);
            if (books == null) {
                return;
            }
            userBooks = BeanUtil.toBean(books, UserBooks.class);
            userBooks.setUserId(LoginHelper.loginUserInfo().getId());
            userBooks.setBookId(books.getId());
            userBooks.setBookType(books.getType());
            if (dto.getType() == 2) {
                userBooks.setLikeStatus(true);
            }
            if (dto.getType() == 1) {
                userBooks.setGiveStatus(true);
            }
            userBooks.setReadId(0L);
            userBooks.setType(false);
            userBooks.setId(IdWorker.getId());
            save(userBooks);
        } else {
            if (dto.getType() == 2) {
                if (userBooks.getLikeStatus()) {
                    return;
                }
                userBooks.setLikeStatus(true);
            }
            if (dto.getType() == 1) {
                if (userBooks.getGiveStatus()) {
                    return;
                }
                userBooks.setGiveStatus(true);
            }
            updateById(userBooks);
        }
        String key = userBooks.getId() + CommonConstants.ACROSS + userBooks.getTitle();
        redisTemplate.opsForHash().increment(RedisConstants.BOOKS, key, 1);
    }

    /**
     * 用户书籍分页接口
     *
     * @param dto
     * @return
     */
    @Override
    public ApiPageEntity<UserBooksPageVO> userBooksPage(UserBooksPageDTO<UserBooks> dto) {
        QueryWrapper<UserBooks> qw = new QueryWrapper<>();
        if (0 == dto.getType() || 4 == dto.getType()) {
            qw.lambda()
                    .eq(UserBooks::getUserId, LoginHelper.loginUserInfo().getId());

        }
        if (1 == dto.getType()) {
            qw.lambda()
                    .eq(UserBooks::getUserId, LoginHelper.loginUserInfo().getId())
                    .eq(UserBooks::getUpdateStatus, 1);
        }
        if (2 == dto.getType()) {
            qw.lambda()
                    .eq(UserBooks::getUserId, LoginHelper.loginUserInfo().getId())
                    .isNotNull(UserBooks::getReadId);
        }
        if (3 == dto.getType()) {
            qw.lambda()
                    .eq(UserBooks::getUserId, LoginHelper.loginUserInfo().getId())
                    .eq(UserBooks::getPayStatus, 1);
        }
        qw.lambda()
                .orderByDesc(UserBooks::getCreateTime);
        Page<UserBooks> iPage = baseMapper.selectPage(dto.getPage(), qw);
        List<UserBooksPageVO> voList = BeanUtil.copyToList(iPage.getRecords(), UserBooksPageVO.class);
        voList.forEach(e -> {
            if (StringUtils.isNotBlank(e.getBookPath())) {
                e.setBookPath(fileUtils.preview(e.getBookPath()));
            }
            if (StringUtils.isNotBlank(e.getCoverPath())) {
                e.setCoverPath(fileUtils.preview(e.getCoverPath()));
            }
        });
        return ApiPageEntity.create(iPage, voList);
    }

    @Override
    public void uploadBooks(MultipartFile file) {
        String filePath = fileUtils.upload(file);
        UserBooks bean = new UserBooks();
        bean.setBookId(-1L);
        bean.setUserId(LoginHelper.loginUserInfo().getId());
        bean.setBookType(-1L);
        bean.setTitle(file.getOriginalFilename());
        bean.setAuthor(LoginHelper.loginUserInfo().getName());
        bean.setBookPath(filePath);
        bean.setCoverPath(filePath);
        bean.setPrice("0");
        bean.setPriceStatus(false);
        bean.setGiveStatus(false);
        bean.setLikeStatus(false);
        bean.setPayStatus(false);
        bean.setUpdateStatus(false);
        bean.setType(true);
        bean.setId(IdWorker.getId());
        bean.setCreateTime(LocalDateTime.now());
        save(bean);
    }
}
